#include "stdafx.h"
#pragma hdrstop

#include "OSMutex.h"


OSMutex::OSMutex()
	: mHandle(::CreateMutex(NULL, false, NULL))
{}

OSMutex::~OSMutex()
{
	if(mHandle != NULL)
		::CloseHandle(mHandle);
}

bool OSMutex::Acquire() const
{
	return (::WaitForSingleObject(mHandle, INFINITE) == WAIT_OBJECT_0);
}

bool OSMutex::Release() const
{
	return ::ReleaseMutex(mHandle);
}

OSMutex::Lock::Lock(const OSMutex& inMutex)
	: mpMutex(&inMutex)
{
	DoAcquire();
}

OSMutex::Lock::Lock(const OSMutex* inpMutex)
	: mpMutex(inpMutex)
{
	DoAcquire();
}

OSMutex::Lock::~Lock()
{
	if(mpMutex)
		mpMutex->Release();
}

void OSMutex::Lock::DoAcquire()
{
	if(mpMutex && !mpMutex->Acquire())
		mpMutex = NULL;
}

OSMutex::Unlock::Unlock(const OSMutex& inMutex)
	: mpMutex(&inMutex)
{
	DoRelease();
}

OSMutex::Unlock::Unlock(const OSMutex* inpMutex)
	: mpMutex(inpMutex)
{
	DoRelease();
}

OSMutex::Unlock::~Unlock()
{
	if(mpMutex)
		mpMutex->Acquire();
}

void OSMutex::Unlock::DoRelease()
{
	if(mpMutex && !mpMutex->Release())
		mpMutex = NULL;
}